home *** CD-ROM | disk | FTP | other *** search
- /* accum.c */
-
- /*
- * Mesa 3-D graphics library
- * Version: 1.2
- * Copyright (C) 1995 Brian Paul (brianp@ssec.wisc.edu)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- * Accumulation buffer.
- */
-
-
- /*
- $Id: accum.c,v 1.14 1995/10/13 22:42:57 brianp Exp $
-
- $Log: accum.c,v $
- * Revision 1.14 1995/10/13 22:42:57 brianp
- * use new DD.set_buffer function
- *
- * Revision 1.13 1995/09/18 14:20:50 brianp
- * call DD.write_span_color with NULL mask, temporary hack
- *
- * Revision 1.12 1995/08/31 21:26:18 brianp
- * use DD.read_color_span instead of dd_read_color_span
- *
- * Revision 1.11 1995/07/24 20:34:16 brianp
- * replaced memset() with MEMSET() and memcpy() with MEMCPY()
- *
- * Revision 1.10 1995/06/12 15:35:00 brianp
- * changed color arrays to GLubyte
- *
- * Revision 1.9 1995/05/22 21:02:41 brianp
- * Release 1.2
- *
- * Revision 1.8 1995/05/12 19:22:23 brianp
- * added #include "macros.h"
- *
- * Revision 1.7 1995/05/12 19:20:19 brianp
- * replaced CC.Mode!=0 with INSIDE_BEGIN_END
- *
- * Revision 1.6 1995/04/11 14:03:27 brianp
- * changed (*CC.write...) to (*DD.write...)
- *
- * Revision 1.5 1995/03/30 21:06:50 brianp
- * updated to use pointers to CC.write_* functions
- *
- * Revision 1.4 1995/03/24 15:28:22 brianp
- * replaced ACCUM_BITS with ACC_TYPE
- *
- * Revision 1.3 1995/03/13 20:54:27 brianp
- * added read buffer logic
- *
- * Revision 1.2 1995/03/04 19:29:44 brianp
- * 1.1 beta revision
- *
- * Revision 1.1 1995/02/24 14:14:02 brianp
- * Initial revision
- *
- */
-
-
- #include <stdlib.h>
- #include <string.h>
- #include "context.h"
- #include "dd.h"
- #include "list.h"
- #include "macros.h"
-
-
-
- /** THIS IS A HACK! See drawpix.c for more info. **/
- #ifdef SHM
- # define MASK NULL
- #else
- # define MASK mask
- #endif
-
-
-
- void glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
- {
- if (CC.CompileFlag) {
- gl_save_clearaccum( red, green, blue, alpha );
- }
- if (CC.ExecuteFlag) {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glAccum" );
- return;
- }
- CC.Accum.ClearColor[0] = CLAMP( red, -1.0, 1.0 );
- CC.Accum.ClearColor[1] = CLAMP( green, -1.0, 1.0 );
- CC.Accum.ClearColor[2] = CLAMP( blue, -1.0, 1.0 );
- CC.Accum.ClearColor[3] = CLAMP( alpha, -1.0, 1.0 );
- }
- }
-
-
-
-
- void gl_accum( GLenum op, GLfloat value )
- {
- GLuint xpos, ypos, width, height;
- GLfloat acc_scale;
-
- if (sizeof(ACC_TYPE)==1) {
- acc_scale = 127.0;
- }
- else {
- /* size of ACC_TYPE==2 */
- acc_scale = 32767.0;
- }
-
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glAccum" );
- return;
- }
-
- if (!CC.AccumBuffer) {
- /* allocate accumulation buffer if not already present */
- CC.AccumBuffer = (ACC_TYPE *)
- malloc( CC.BufferWidth * CC.BufferHeight * 4 * sizeof(ACC_TYPE) );
- if (!CC.AccumBuffer) {
- /* unable to setup accumulation buffer */
- gl_error( GL_OUT_OF_MEMORY, "glAccum" );
- return;
- }
- }
-
- /* Determine region to operate upon. */
- if (CC.Scissor.Enabled) {
- xpos = CC.Scissor.X;
- ypos = CC.Scissor.Y;
- width = CC.Scissor.Width;
- height = CC.Scissor.Height;
- }
- else {
- /* whole window */
- xpos = 0;
- ypos = 0;
- width = CC.BufferWidth;
- height = CC.BufferHeight;
- }
-
- switch (op) {
- case GL_ADD:
- {
- ACC_TYPE ival, *acc;
- GLuint i, j;
-
- ival = (ACC_TYPE) (value * acc_scale);
- for (j=0;j<height;j++) {
- acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
- for (i=0;i<width;i++) {
- *acc += ival; acc++; /* red */
- *acc += ival; acc++; /* green */
- *acc += ival; acc++; /* blue */
- *acc += ival; acc++; /* alpha */
- }
- ypos++;
- }
- }
- break;
- case GL_MULT:
- {
- ACC_TYPE *acc;
- GLuint i, j;
-
- for (j=0;j<height;j++) {
- acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
- for (i=0;i<width;i++) {
- *acc = (ACC_TYPE) ( (GLfloat) *acc * value ); acc++; /*r*/
- *acc = (ACC_TYPE) ( (GLfloat) *acc * value ); acc++; /*g*/
- *acc = (ACC_TYPE) ( (GLfloat) *acc * value ); acc++; /*g*/
- *acc = (ACC_TYPE) ( (GLfloat) *acc * value ); acc++; /*a*/
- }
- ypos++;
- }
- }
- break;
- case GL_ACCUM:
- {
- ACC_TYPE *acc;
- GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
- GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
- GLfloat rscale, gscale, bscale, ascale;
- GLuint i, j;
-
- (void) (*DD.set_buffer)( CC.Pixel.ReadBuffer );
-
- /* Accumulate */
- rscale = value * acc_scale / CC.RedScale;
- gscale = value * acc_scale / CC.GreenScale;
- bscale = value * acc_scale / CC.BlueScale;
- ascale = value * acc_scale / CC.AlphaScale;
- for (j=0;j<height;j++) {
- (*DD.read_color_span)( width, xpos, ypos,
- red, green, blue, alpha);
- acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
- for (i=0;i<width;i++) {
- *acc += (ACC_TYPE) ( (GLfloat) red[i] * rscale ); acc++;
- *acc += (ACC_TYPE) ( (GLfloat) green[i] * gscale ); acc++;
- *acc += (ACC_TYPE) ( (GLfloat) blue[i] * bscale ); acc++;
- *acc += (ACC_TYPE) ( (GLfloat) alpha[i] * ascale ); acc++;
- }
- ypos++;
- }
-
- (void) (*DD.set_buffer)( CC.Color.DrawBuffer );
- }
- break;
- case GL_LOAD:
- {
- ACC_TYPE *acc;
- GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
- GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
- GLfloat rscale, gscale, bscale, ascale;
- GLuint i, j;
-
- (void) (*DD.set_buffer)( CC.Pixel.ReadBuffer );
-
- /* Load accumulation buffer */
- rscale = value * acc_scale / CC.RedScale;
- gscale = value * acc_scale / CC.GreenScale;
- bscale = value * acc_scale / CC.BlueScale;
- ascale = value * acc_scale / CC.AlphaScale;
- for (j=0;j<height;j++) {
- (*DD.read_color_span)( width, xpos, ypos,
- red, green, blue, alpha);
- acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
- for (i=0;i<width;i++) {
- *acc++ = (ACC_TYPE) ( (GLfloat) red[i] * rscale );
- *acc++ = (ACC_TYPE) ( (GLfloat) green[i] * gscale );
- *acc++ = (ACC_TYPE) ( (GLfloat) blue[i] * bscale );
- *acc++ = (ACC_TYPE) ( (GLfloat) alpha[i] * ascale );
- }
- ypos++;
- }
-
- (void) (*DD.set_buffer)( CC.Color.DrawBuffer );
- }
- break;
- case GL_RETURN:
- {
- GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
- GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
- GLubyte mask[MAX_WIDTH];
- ACC_TYPE *acc;
- GLfloat rscale, gscale, bscale, ascale;
- GLint rmax, gmax, bmax, amax;
- GLuint i, j;
-
- MEMSET( mask, 1, width ); /* set write mask to all 1's */
- rscale = value / acc_scale * CC.RedScale;
- gscale = value / acc_scale * CC.GreenScale;
- bscale = value / acc_scale * CC.BlueScale;
- ascale = value / acc_scale * CC.AlphaScale;
- rmax = (GLint) CC.RedScale;
- gmax = (GLint) CC.GreenScale;
- bmax = (GLint) CC.BlueScale;
- amax = (GLint) CC.AlphaScale;
- for (j=0;j<height;j++) {
- acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
- for (i=0;i<width;i++) {
- GLint r, g, b, a;
- r = (GLint) ( (GLfloat) (*acc++) * rscale );
- g = (GLint) ( (GLfloat) (*acc++) * gscale );
- b = (GLint) ( (GLfloat) (*acc++) * bscale );
- a = (GLint) ( (GLfloat) (*acc++) * ascale );
- red[i] = CLAMP( r, 0, rmax );
- green[i] = CLAMP( g, 0, gmax );
- blue[i] = CLAMP( b, 0, bmax );
- alpha[i] = CLAMP( a, 0, amax );
- }
- (*DD.write_color_span)( width, xpos, ypos,
- red, green, blue, alpha, MASK );
- ypos++;
- }
- }
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glAccum" );
- }
- }
-
-
-
-
- void glAccum( GLenum op, GLfloat value )
- {
- if (CC.ExecuteFlag) {
- gl_accum( op, value );
- }
- if (CC.CompileFlag) {
- gl_save_accum( op, value );
- }
- }
-
-
-
- /*
- * Clear the accumulation buffer.
- */
- void gl_clear_accum_buffer( void )
- {
- GLuint buffersize;
- GLfloat acc_scale;
-
- if (sizeof(ACC_TYPE)==1) {
- acc_scale = 127.0;
- }
- else {
- /* size of ACC_TYPE==2 */
- acc_scale = 32767.0;
- }
-
-
- buffersize = CC.BufferWidth * CC.BufferHeight; /* number of pixels */
-
- if (!CC.AccumBuffer) {
- /* try to alloc accumulation buffer */
- CC.AccumBuffer = (ACC_TYPE *)
- malloc( buffersize * 4 * sizeof(ACC_TYPE) );
- }
-
- if (CC.AccumBuffer) {
- if (CC.Scissor.Enabled) {
- /* Limit clear to scissor box */
- ACC_TYPE r, g, b, a;
- GLint x, y, i;
- r = (ACC_TYPE) (CC.Accum.ClearColor[0] * acc_scale);
- g = (ACC_TYPE) (CC.Accum.ClearColor[1] * acc_scale);
- b = (ACC_TYPE) (CC.Accum.ClearColor[2] * acc_scale);
- a = (ACC_TYPE) (CC.Accum.ClearColor[3] * acc_scale);
- for (y=CC.Scissor.Ymin; y<=CC.Scissor.Ymax; y++) {
- for (x=CC.Scissor.Xmin; x<=CC.Scissor.Xmax; x++) {
- i = 4 * (y * CC.BufferWidth + x);
- CC.AccumBuffer[i+0] = r;
- CC.AccumBuffer[i+1] = g;
- CC.AccumBuffer[i+2] = b;
- CC.AccumBuffer[i+3] = a;
- }
- }
- }
- else {
- /* clear whole buffer */
- if (CC.Accum.ClearColor[0]==0.0 &&
- CC.Accum.ClearColor[1]==0.0 &&
- CC.Accum.ClearColor[2]==0.0 &&
- CC.Accum.ClearColor[3]==0.0) {
- /* Black */
- MEMSET( CC.AccumBuffer, 0, buffersize * 4 * sizeof(ACC_TYPE) );
- }
- else {
- /* Not black */
- ACC_TYPE *acc, r, g, b, a;
- GLuint i;
-
- acc = CC.AccumBuffer;
- r = (ACC_TYPE) (CC.Accum.ClearColor[0] * acc_scale);
- g = (ACC_TYPE) (CC.Accum.ClearColor[1] * acc_scale);
- b = (ACC_TYPE) (CC.Accum.ClearColor[2] * acc_scale);
- a = (ACC_TYPE) (CC.Accum.ClearColor[3] * acc_scale);
- for (i=0;i<buffersize;i++) {
- *acc++ = r;
- *acc++ = g;
- *acc++ = b;
- *acc++ = a;
- }
- }
- }
- }
- }
-